import pandas as pd
import numpy as np
import statsmodels.api as sm

# 生成示例数据（假设df1已经定义并包含所需数据）

np.random.seed(42)  # 设置随机种子以确保结果可重复

n_samples = 1000

# 生成合成数据

data = {
    'closes': np.random.normal(100, 10, n_samples),  # 收盘价

    'vol': np.random.normal(100000, 5000, n_samples),  # 成交量

    'amount': np.random.normal(5000000, 200000, n_samples),  # 成交额

    'buy_sm_vol': np.random.normal(1000, 50, n_samples),  # 小单买入量

    'sell_sm_vol': np.random.normal(1000, 50, n_samples),  # 小单卖出量

    'buy_md_vol': np.random.normal(5000, 200, n_samples),  # 中单买入量

    'sell_md_vol': np.random.normal(5000, 200, n_samples),  # 中单卖出量

    'buy_lg_vol': np.random.normal(10000, 500, n_samples),  # 大单买入量

    'sell_lg_vol': np.random.normal(10000, 500, n_samples),  # 大单卖出量

    'buy_elg_vol': np.random.normal(50000, 2000, n_samples),  # 特大单买入量

    'sell_elg_vol': np.random.normal(50000, 2000, n_samples),  # 特大单卖出量

}

df1 = pd.DataFrame(data)

# 增加一列，股票的涨跌幅

df1['zd_close'] = df1['closes'].shift(1)

# 处理缺失值

df1 = df1.dropna(subset=['zd_close']).reset_index(drop=True)

numeric_cols = df1.select_dtypes(include=['number']).columns.tolist()

# 选择需要进行主成分分析的自变量

X = df1[['vol', 'amount', 'buy_sm_vol', 'sell_sm_vol', 'buy_md_vol', 'sell_md_vol', 'buy_lg_vol', 'sell_lg_vol', 'buy_elg_vol', 'sell_elg_vol']]

# 计算特征值和特征向量

eigenvalues, eigenvectors = np.linalg.eig(np.cov(X, rowvar=False))
print('累计贡献率为：', round(eigenvalues[:5].sum() / eigenvalues.sum(), 4) * 100, '%')

# 选择要保留的主成分个数

n_components = 5
top_eigenvectors = eigenvectors[:, :n_components]

# 计算主成分

principal_components = np.dot(X, top_eigenvectors)

# 将主成分添加到原数据中

data_pca = pd.concat([df1, pd.DataFrame(principal_components, columns=[f'PC{i+1}' for i in range(n_components)])], axis=1)

# 添加常数列前确保数据类型正确

X_pca = data_pca[[f'PC{i+1}' for i in range(n_components)]].copy()
X_pca = sm.add_constant(X_pca)

# 确保y的索引与X_pca一致

y = df1['zd_close'].copy()

# 构建回归模型

model_pca = sm.OLS(y, X_pca)

# 拟合模型

result_pca = model_pca.fit()

# 输出结果

print("\n回归模型结果:")
print(result_pca.summary())

# 选择PC1, PC3, PC4作为新的自变量

X_pca_selected = data_pca[['PC3', 'PC4', 'PC5']]
X_pca_selected.columns = ['PC3', 'PC4', 'PC5']

# 添加常数列

X_pca_selected = sm.add_constant(X_pca_selected)

# 如果需要查看选择后的模型结果，可以取消以下代码的注释：

model_pca_selected = sm.OLS(y, X_pca_selected)
result_pca_selected = model_pca_selected.fit()
print("\n选择后的回归模型结果:")
print(result_pca_selected.summary())